OpenClaw gateway 的两种「重启」:软重启与真重启,别被返回的成功骗了

本文摘要背景在排查上面那个「定时任务卡死」问题时,遇到了第二个坑:定时任务卡死后留下了一个僵尸运行锁,导致后续所有新任务都无法启动(一直提示 already-running)。清理这个锁的过程,让我意识到 gateway 有两种"重启",很多人(包括当时的我)只知其一会踩坑。过程问题描述定时任务运行到一半卡死/超时后,任务记录里 running 状态一直占着,怎么都清不掉,新任务一跑就报 already-...

gateway 的两种「重启」

背景

在排查上面那个「定时任务卡死」问题时,遇到了第二个坑:定时任务卡死后留下了一个僵尸运行锁,导致后续所有新任务都无法启动(一直提示 already-running)。清理这个锁的过程,让我意识到 gateway 有两种"重启",很多人(包括当时的我)只知其一会踩坑。

过程

问题描述

定时任务运行到一半卡死/超时后,任务记录里 running 状态一直占着,怎么都清不掉,新任务一跑就报 already-running

排查 / 调研

  1. 直接改数据库清锁:任务状态存在 SQLite 里,把 running_at_ms 字段手动置空。结果:改了文件,但 cron get 查出来还是显示 running
  2. 用管理工具的重启命令:执行 gateway 的重启指令,返回了"重启成功"。但一看进程,PID 没变、启动时间还是几天前——根本没真正重启进程,只是发了一个重启信号/钩子。
  3. 手动杀进程:容器里 gateway 由 tini(1 号进程)托管,直接 kill -TERM <gatewayPID>,tini 自动重新拉起来一个全新的 gateway 进程。这次 PID 变了、启动时间刷新了,僵尸锁也随之消失,新任务能正常跑了。

根因

  • 数据库文件 ≠ 运行时内存:gateway 运行时把任务状态缓存在内存里。直接改磁盘上的数据库文件,内存里的状态不会跟着变,所以查出来还是旧的 running。
  • 「管理工具的重启」可能是"软重启":它返回"成功"但只是发射了重启钩子/信号,进程本身没轮换,内存没清,锁自然还在。
  • 真正轮换进程:在容器里,进程由 init 进程(tini)托管,只有让 gateway 进程真正退出、被 tini 重新拉起,才会得到干净的内存状态。

解决方案

  • 清僵尸锁:容器内 kill -TERM <gatewayPID>,让 tini 自动 respawn 一个全新进程。
  • 判断是否真重启:看进程 PID 是否变化 + 启动时间是否刷新,而不是看管理工具返回"成功"。

总结

正确做法

  1. 判断进程是否真重启,看 PID 和启动时间,别只看工具返回
  2. 改数据库文件清运行时状态,通常无效——运行时状态在内存里,磁盘改动不生效。
  3. 容器环境里要"干净重启、清内存态",kill -TERM <PID> 让 init 进程自动拉起新实例是最直接可靠的做法。
  4. 定时任务的僵尸运行锁典型特征:进程已死但记录仍显示 running,新的运行全部被拒。这种要靠重启进程解决,不是清数据库。

参考

觉得内容不错?我要

评论 暂无评论
暂无评论,快来抢沙发吧~